import test_framework.test.unit.TestCase;
import mx.utils.Delegate;

import gugga.sequence.TaskManager;
import gugga.sequence.FictiveTask;
import gugga.sequence.ExecuteAsyncMethodTask;
import gugga.common.EventDescriptor;

import guggaLibTests.support.TaskExecutionEvaluator;
import guggaLibTests.support.PauseResumeMethodsSequence;

import gugga.common.ITask;
import gugga.sequence.PreconditionsTask;
import gugga.sequence.PreconditionsManager;
import gugga.utils.DebugUtils;
import mx.events.EventDispatcher;
import gugga.debug.Debugger;

import gugga.sequence.SingleExecutionTask;
import test_framework.test.unit.info.AssertFalseInfo;
import gugga.debug.Assertion;
import gugga.sequence.WaitingTask;
import gugga.sequence.CustomCompleteTask;

/**
 * @author stefan
 */
class guggaLibTests.CustomCompleteTaskTest extends TestCase 
{
	private var delayInterval:Number = 1000;
	
	public function CustomCompleteTaskTest ()
	{
		super();

		this.delayInterval = 1000;
	}
	
	public function testConstructor ()
	{
		var task : ITask = new CustomCompleteTask();
		
		assertInstanceOf(
			"the task should be an instance of class CustomCompleteTask",
			task,
			CustomCompleteTask
		);
	}
	
	public function testComplexBehaviour ()
	{
		var manager : TaskManager = new TaskManager(true);
		var evaluator : TaskExecutionEvaluator = new TaskExecutionEvaluator(this);
		
		var task1 : ITask = new FictiveTask();
		var task2 : CustomCompleteTask = new CustomCompleteTask();
		var task3 : ITask = new FictiveTask();
		
		manager.addStartingTask(task1);
		manager.addTaskPredecessor(task2, task1);
		manager.addTaskPredecessor(task3, task2);
		
		manager.addEventListener(
			"start",
			Delegate.create(evaluator, evaluator.onTaskStarted)
		);
		manager.addEventListener(
			"completed",
			Delegate.create(evaluator, evaluator.onTaskCompleted)
		);
		task1.addEventListener(
			"start",
			Delegate.create(evaluator, evaluator.onTaskStarted)
		);
		task1.addEventListener(
			"completed",
			Delegate.create(evaluator, evaluator.onTaskCompleted)
		);
		task2.addEventListener(
			"start",
			Delegate.create(evaluator, evaluator.onTaskStarted)
		);
		task2.addEventListener(
			"completed",
			Delegate.create(evaluator, evaluator.onTaskCompleted)
		);
		task3.addEventListener(
			"start",
			Delegate.create(evaluator, evaluator.onTaskStarted)
		);
		task3.addEventListener(
			"completed",
			Delegate.create(evaluator, evaluator.onTaskCompleted)
		);
		
		var firstBlock = function ()
		{
			evaluator.registerRequiredTaskStatus( {task: manager, event: "start"} );
			evaluator.registerRequiredTaskStatus( {task: task1, event: "start"} );
			evaluator.registerRequiredTaskStatus( {task: task1, event: "completed"} );
			evaluator.registerRequiredTaskStatus( {task: task2, event: "start"} );
			
			manager.start();
		};
		
		var secondBlock = function ()
		{
			evaluator.evaluateTaskExecution();
			evaluator.assertTaskStatusRegisterEqualsRequiredTaskStatusRegister("the CustomCompleteTask should not fire any more events right after start");
			
			task2.complete();
						
			evaluator.registerRequiredTaskStatus( {task: task2, event: "completed"} );
			evaluator.registerRequiredTaskStatus( {task: task3, event: "start"} );
//			evaluator.registerRequiredTaskStatus( {task: task3, event: "completed"} );
			evaluator.registerRequiredTaskStatus( {task: manager, event: "completed"} );
		};
		
		var thirdBlock = function ()
		{
			evaluator.evaluateTaskExecution();
			evaluator.assertTaskStatusRegisterEqualsRequiredTaskStatusRegister("the CustomCompleteTask should complete");
		};
		
		var pauseAndResumer : PauseResumeMethodsSequence = new PauseResumeMethodsSequence(
			this,
			1000,
			[firstBlock,
			secondBlock,
			thirdBlock]
		);
	}
}